x86: vioapic: fix remote irr bit setting for level triggered interrupts
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 28 Oct 2009 10:59:14 +0000 (10:59 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 28 Oct 2009 10:59:14 +0000 (10:59 +0000)
Clear all entries' remote irr bits once the RTE entries' vector field
match with EOI message's vector.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
xen/arch/x86/hvm/vioapic.c

index 5a4d82730ed4c2228d92bbd3d2f82795bc9c4f29..9c0033a23e3ca347c27c6c391d6a0ae6300a12e6 100644 (file)
@@ -384,17 +384,6 @@ void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
     }
 }
 
-static int get_eoi_gsi(struct hvm_hw_vioapic *vioapic, int vector)
-{
-    int i;
-
-    for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
-        if ( vioapic->redirtbl[i].fields.vector == vector )
-            return i;
-
-    return -1;
-}
-
 void vioapic_update_EOI(struct domain *d, int vector)
 {
     struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
@@ -404,32 +393,30 @@ void vioapic_update_EOI(struct domain *d, int vector)
 
     spin_lock(&d->arch.hvm_domain.irq_lock);
 
-    if ( (gsi = get_eoi_gsi(vioapic, vector)) == -1 )
+    for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ )
     {
-        gdprintk(XENLOG_WARNING, "Can't find redir item for %d EOI\n", vector);
-        goto out;
-    }
-
-    ent = &vioapic->redirtbl[gsi];
+        ent = &vioapic->redirtbl[gsi];
+        if ( ent->fields.vector != vector )
+            continue;
 
-    ent->fields.remote_irr = 0;
+        ent->fields.remote_irr = 0;
 
-    if ( iommu_enabled )
-    {
-        spin_unlock(&d->arch.hvm_domain.irq_lock);
-        hvm_dpci_eoi(current->domain, gsi, ent);
-        spin_lock(&d->arch.hvm_domain.irq_lock);
-    }
+        if ( iommu_enabled )
+        {
+            spin_unlock(&d->arch.hvm_domain.irq_lock);
+            hvm_dpci_eoi(d, gsi, ent);
+            spin_lock(&d->arch.hvm_domain.irq_lock);
+        }
 
-    if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
-         !ent->fields.mask &&
-         hvm_irq->gsi_assert_count[gsi] )
-    {
-        ent->fields.remote_irr = 1;
-        vioapic_deliver(vioapic, gsi);
+        if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
+             !ent->fields.mask &&
+             hvm_irq->gsi_assert_count[gsi] )
+        {
+            ent->fields.remote_irr = 1;
+            vioapic_deliver(vioapic, gsi);
+        }
     }
 
- out:
     spin_unlock(&d->arch.hvm_domain.irq_lock);
 }